/*
 * @: 
 * @Version: 1.0
 * @Autor: ziwei
 * @Date: 2021-06-30 09:45:32
 * @LastEditors: ziwei
 * @LastEditTime: 2021-09-27 18:13:41
 */
import { createWebHashHistory } from './history/hash';
import {createWebHistory} from './history/html5'; 
import {computed, shallowRef, unref} from 'vue'; 
//数据处理 options.routes 用户的配置 难以理解不好维护
function normalizeRouteRecord(record) {//格式化用户参数
    return {
        path: record.path,//状态机  计息路径的分数 算出匹配规则
        meta: record.meta||{},//备注信息
        beforeEnter: record.beforeEnter,
        name:record.name,
        components:{
            default:record.component //循环
        },
        children:record.children||[]
    };
}

function createRouterWatcher(record,parent) {//创建匹配记录 构建父子关系
    //record 中的path 做一些修改 正则的情况
    const matcher = {
        path:record.path,
        record,
        parent,
        children:[]
    };
    if (parent){
        parent.children.push(matcher)
    }
    return matcher;
}

//树的遍历
function createRouterMatcher(routes) {
    const matchers = [];
    function addRoute(route,parent) {
        let nomarlizedRecord = normalizeRouteRecord(route)
        if (parent) {
          nomarlizedRecord.path = parent.path + nomarlizedRecord.path
        }

        const matcher = createRouterMatcher(nomarlizedRecord);
        if('children' in normalizeRouteRecord){
            let children = normalizeRouteRecord.children;
            for(let i=0;i<children.length;i++){
                addRoute(children[i],matcher)
            }
        }
        matchers.push(matcher);
    }
    routes.forEach(route => addRoute(route))
    console.log("matchers",matchers);
    return {
        addRoute //动态添加路由 面试问路由 如何动态添加 就是这个api
    }
    console.log(matchers);
}

//初始化路由系统的默认参数
const START_LOCATION_NORMALIZED = {
  path:"/",
  // params:{},//路径参数
  // query:{},
  matched:[],//当前路径匹配到的记录
}
function createRouter(options) {
    const routerHistory = options.history;
    const matcher = createRouterMatcher(options.routes);//格式化路由配置 拍平

    //后续改变这个数据value 就可以更新视图了
    const currentRoute = shallowRef(START_LOCATION_NORMALIZED ); //obj.value= 响应式数据 reactive:取出的值不是响应式的 computed


    //let {path} = reactive(reactiveRoute);// reactive 会自动取出
    //console.log(path);
    //将数组的计算属性 再次包裹

    //vue2 中有两个属性 $router里面包含的是方法  $route里面包含属性
    console.log("matcher",matcher);
    const options//格式化路由的配置 拍平
    const router ={
        push(){

        },
        repalce(){

        },
        install(app){//路由的核心就是页面切换重新渲染
            const router = this;
            app.config.globalProperties.$router = router;
            Object.defineProperty(app.config.globalProperties,'$route',{
              enumerable:true,
              get:()=>unref(currentRoute)
            })

            const reactiveRoute = {}
            for(let key in START_LOCATION_NORMALIZED){//所有值都是响应式的
              reactiveRoute[key]=computed(()=>currentRoute.value[key])
            }

            console.log("路由的安装");
            app.provide('router',router)
            app.provide('route location',reactuve(reactiveRoute))
            
            app.component("Routerlink",{
              //slots attrs emit expose vue3的用法
                setup: (props, { slots }) = () => <a>{slots.default && slots.default()}</a>
            })
            app.component("RouterView", {
                setup: (props, { slots }) = () => <div></div>
            })
            //后续还有逻辑
            //解析路径 RouterLink RouterView 实现 页面的钩子 从离开到进入 到解析完成
        }
    }
    return router;
}

export {
    createRouter, createWebHashHistory, createWebHistory
}